%% k-近邻算法k- nearest neighbor algorithm
function [cou,label1]=KNN(training,testing,k,m)
% 输入训练样本和测试样本
% 训练样本每一行代表一个样本，最后一列为样本对应响应y。
% 测试样本每一行为一个样本，有响应，响应可用来计算准确性。
% k为近邻算法个数k
% m=1时表示分类，m=2时表示预测
[row, column]=size(training);
[row1,column1]=size(testing);%计算测试集与训练集的距离
distance=[];% 距离初始化
for i=1:row1 % 对于每一个测试样本
    distance(i,:)=sqrt(sum((repmat(testing(i,1:end-1),row,1)- ...
        training(:,1:(column-1))).^2, 2));
    % 计算该测试样本到所有训练样本距离(此处距离计算为欧式距离)
end
% 寻找K近邻
label=[];%存储距离测试样本最近的K个值
for i=1:row1
    [a,b]=sort(distance(i,:));%排序,b存储distance中值的原横坐标
    for j=1:k
        label(i,j)=training(b(j),column);% 获得测试数据k近邻样本的响应
    end
end
cl=zeros(1,row);
count=1;
cl(1,1)=training(1,column);% 统计预测结果类型
for i=2:row % 统计响应有多少种，将结果放在cl中。
    A=training(i,column);% 第i行训练数据响应
    flag=0;
    for j=1:count
        if cl(1,j)==A
            flag=1;
            break;
        end
    end
    if flag==0
        count=count+1;
        cl(1,count)=A;
    end
end
end_count=zeros(row1,count);%统计某个结果出现的次数
for i=1:row1
    for j=1:k
        for l=1:count
            if label(i,j)==cl(1,l)
                end_count(i,l)=end_count(i,l)+1;
            end
        end
    end
end
cou=0;
label1=[];%统计预测结果
for i=1:row1
    if(m==1)
        k=1;
        num=end_count(i,1);
        for j=2:count
            if num<end_count(i,j)
                k=j;
                num=end_count(i,j);
            end
        end
        label1(i)=cl(1,k);
        if testing(i,column1)==label1(i)
            cou=cou+1;
        end
    elseif(m==2)
        label1(i)=mean(label(i,:));
    end
end
if(m==1)
    cou=cou/row1;
elseif(m==2)
    cou=mean(abs(testing(:,end)-label1)./testing(:,end));
end
% 版权声明：本文改编自CSDN博主「MyNameGZG」的原创文章，遵循CC 4.0 BY-SA版权协议，转载请附上原文出处链接及本声明。
% 原文链接：https://blog.csdn.net/MyNameGZG/article/details/90406336